home *** CD-ROM | disk | FTP | other *** search
- Tech Chapter 1 - Relation format
- MetalBase 5.1
- -------------------------------------------------------------------------------
-
- MetalBase keeps track of all data in a single file (.REL
- extension), with
- the exception of multi-length fields--data for those is stored
- in a second
- file (.DAT extension).
-
- The .REL file consists of a header containing descriptions of
- fields and
- indices, followed by any number of fixed-length records. Each
- record
- actually consists of index information for a tuple, followed
- by a tuple's
- record data (for each multi-length field, a pointer to an
- offset in the
- .DAT file is stored).
-
-
- FIELD TYPES
- -------------------------------------------------------------------
-
- Each field in a record is one of a number of intrinsic types;
- user-defined
- types aren't supported (I was gonna put that in 4.1, but never
- bothered.
- I'm glad I didn't now). Valid field types are:
-
- Enum Name Storage Typedef From Expected length
- ----------- --------- ----------------- ---------------
- T_CHAR.......char [].......................any (fixed)**
- T_SHORT......short.........................two bytes
- T_USHORT.....ushort.....unsigned short.....two bytes
- T_LONG.......long..........................four bytes
- T_ULONG......ulong......unsigned long......four bytes
- T_FLOAT......float.........................four bytes
- T_DOUBLE.....double........................eight bytes
- T_MONEY......double........................eight bytes
- T_TIME.......mb_time....long...............four bytes
- T_DATE.......mb_date....long...............four bytes
- T_SERIAL.....long..........................four bytes
- T_PHONE......mb_phone...struct mb_phone....varies (fixed)*
- T_BYTE.......byte []....unsigned char []...any (fixed)**
- T_MCHAR......mchar......struct mchar.......varies (fixed)*
- T_MBYTE......mbyte......struct mbyte.......varies (fixed)*
-
- * the length of these fields depends on the structure-packing
- algorithm used by the local compiler.
-
- ** the length of these fields is decided when the relation is
- first built, and remains constant for each record.
-
-
- FIELD DESCRIPTIONS
- ------------------------------------------------------------
-
-
- T_MCHAR, T_MBYTE:
- See the chapter on multi-length fields for an in-depth
- description of how
- these fields are implemented.
-
-
- T_TIME and T_DATE:
- These fields are stored as longs; information is stored in
- such an order
- that more relevant information is stored in higher bits--in
- this way,
- these fields can be sorted as if they were of type T_LONG and
- will
- be sorted meaningfully even when parsed.
-
- Bits in time field:
- 00000000 hhhhhmmm mmmsssss suuuuuuu --
- h=hour,m=min,s=sec,u=microseconds
-
- Bits in date field:
- 00000000 00yyyyyy yyyyyyym mmmddddd --y=year,m=month,d=day
-
-
- T_MONEY:
- Money is treated exactly as double, but is rounded to 2
- decimal places
- before being written or compared. MetalBase releases prior to
- 5.1 used
- the obvious algorithm for this--
-
- X = floor ( (long)(X * 100.0) ) / 100.0
-
- --but this doesn't work on most systems (it introduces huge
- floating-point
- problems--try, for example, 34.16 in a T_MONEY field in 5.0).
- Sad state of
- the world. The routine "double tomoney (double);" has been
- provided with
- release 5.1 to correct this problem.
-
-
- T_SERIAL:
- Serial fields are T_LONGs which are automatically filled
- before a call to
- mb_add() or mb_add_q(). Calls to mb_upd() verify that the
- value of these
- fields has not changed since the record being updated was
- first retrieved;
- in this way, each record can be stamped with an indelible
- number. The first
- serial value assigned will be zero unless specified otherwise
- during
- creation of the relation; it is incremented on each successive
- add, and
- never decremented (even if a record is deleted).
-
-
- T_PHONE:
- In MetalBase 5.0, phone number fields were stored as 20-
- character fields
- which were formatted into a fixed form before being stored.
- MetalBase 5.1,
- and hopefully all later versions, use a structure consisting
- of three
- shorts (area code, prefix and number) and one long
- (extension).
-
-
- T_BYTE:
- These are used just about like char, save that if you index
- them, searches
- won't stop at the first zero in the string (as they would for
- strings).
- The routines hextostr() and strtohex() are used by MB_INPUT
- for data-entry
- of byte fields.
-
-
- RELATION FORMAT
- ---------------------------------------------------------------
-
-
- Pos #/Bytes Description
-
- 0 1.......(char)51 : 5.1 signature
- 1 1.......Bit 1: Work flag -- set if relation is being
- updated
- Bit 2: fMulti -- set if relation has multi-
- length fields
- Bit 3: fCorrupt -- set if relation was found
- to be corrupt
- 2 4.......Number of unindexed records
- 6 4.......Pointer to fields' decriptions => :A
- 10 4.......Pointer to indices' decriptions => :B
- 14 4.......Pointer to record 0 => :C
- 18 4.......Number of records
- 22 4.......Next serial field value
- 26 2.......Number of fields
- 28 2.......Number of indices
- 30 4*I.....Pointers to index-heading records (top record
- in each tree)
-
- A: var*F...Fields' descriptions:
- byte 0 : Type (0-10, as listed above)
- bytes 1-2 : Size (short/ used only for char
- fields)
- bytes 3-? : Name (max len = 20, terminated
- by '|')
-
- B: var*I...Indices' descriptions:
- byte 0 : Type (0-1, 0==nodups, 1==dups)
- bytes 1 : Number of fields in this index
- bytes 2-? : Name (max len = 20, terminated
- by ':')
- --- : Each field's sequential # (as
- short, 0-based)
-
- ?: 1.......(char)1 if encryption mask chosen yet; (char)0
- if not
- ?: 1.......Encryption mask; 0 indicates no encryption
- ?: 126.....Unused since 5.0 (reserved space for later MB
- versions)
- ?: 1.......Separator ('0)
-
- C: var*R...Records:
- 13 bytes for each index: Index information
- Bytes 0-3 : Left-child (record #)
- Bytes 4-7 : Right-child (record #)
- Bytes 8-11 : Parent (record #)
- Byte 12 : Balance (';'=-2 '<'=-1 '='=0
- '>'=1 '?'=2)
- recsize bytes : Record information (no field
- separators)
- 1 byte separator ('0)
-
- D: var*R...Unindexed records:
- 13 zeroes for each index, reserved for later
- indexing
- recsize bytes: Record information (no field
- separators)
- 1 byte separator ('0)
-
-
- Actual record information is stored as it looks in memory
- structures; thus,
- relations will not be portable between machines unless the
- same structure-
- packing algorithm is used on both systems.
-
-
- DATA-FILE FORMAT
- --------------------------------------------------------------
-
-
- Pos #/Bytes Description
-
- 0 1.......(char)51 : 5.1 signature
- 1 4.......offset of first free-space chain link
-
- The chapter on multi-length fields describes the use of this file
- in more
- detail. Essentially, the .DAT file is a threaded heap, where
- only the
- scattered blocks of free space are chained. The byte-offsets
- of "used"
- blocks are stored in the .REL file as pointers to data;
- however, the .DAT
- file has no such link back to the appropriate record numbers
- in the .REL
- file. This was done for performance reasons, and doesn't
- really impact
- the recovery of data within corrupt .REL/.DAT files (as you're
- basically
- hosed anyway if things get bad).
-
- Pos #/Bytes Description
-
- n+0 4.......byte-offset of next link in the free chain, or
- 0L if at end
- n+4 4.......number of bytes in this block, including these
- 8
-
-